#include "engine.h"
#include "enginedata.h"
#include "qkeymetro.h"
#include "port.h"
#include "buffer.h"
#include "poolableobject.h"
#include "oscillator.h"
#include "sequencer.h"
#include "mtime.h"
#include <QMutex>

using namespace QKeyMetro;

//bool Engine::isFinishing_ = false;


Engine::Engine(QObject * parent) :
        //QObject(parent),
        waitCondition_(NULL),
        //thread_(),
        outPort_(new Port(true, NC_STEREO,QString("Out"))),
        inPort_(new Port(false, NC_STEREO,QString("In"))) ,
        osc_(new Oscillator),
        isFinishing_(false),
        data_(new EngineData()),
        seq_(new Sequencer())
{
}

Engine::~Engine(){

    isFinishing_ = true;
    waitCondition_->wakeAll();
    sleep(1);
    terminate();
}


void Engine::setSampleRate(int sampleRate){
    StaticData::sampleRate = sampleRate;
/*    for (int i = 0; i<StaticData::pool.size(); ++i)
        if (StaticData::pool.at(i)->getType() == PoolableObject::MTIME) ((MTime * )StaticData::pool.at(i))->recalcSampleTime();
        */
}

void Engine::setBufSize(int bufSize){
    StaticData::bufSize = bufSize;
    for (int i = 0; i<StaticData::pool.size(); ++i)
        if (StaticData::pool.at(i)->getType() == PoolableObject::BUFFER) ((Buffer * )StaticData::pool.at(i))->changeSize(bufSize);
    StaticData::log(QString("bufsize is changed to %1").arg(StaticData::bufSize));
}


void Engine::setWaitCondition(QWaitCondition & waitCondition){
    waitCondition_= & waitCondition;
}

Port & Engine::getPort(bool isOut){
    return isOut ? *outPort_ : *inPort_;

}


void Engine::run(){
    QKeyMetro::StaticData::log("ENG: thread started...");
    QMutex mutex;
    while (not isFinishing_){
        mutex.lock();
        waitCondition_->wait(&mutex);
        osc_->getNextFrame(outPort_->getBuffer(0));
        mutex.unlock();
    }
    QKeyMetro::StaticData::log("ENG: thread stopped...");
}

